package com.quectel.cms.controller.patrol;


import com.quectel.cms.controller.BaseController;
import com.quectel.cms.util.SessionHolder;
import com.quectel.constant.OrderCodePrefixConstants;
import com.quectel.constant.core.workorder.WorkOrderConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.core.module.patrol.dto.VideoPatrolEventReportDto;
import com.quectel.core.module.patrol.service.VideoPatrolEventReportService;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.core.module.workorder.dto.WorkOrderDto;
import com.quectel.core.module.workorder.dto.WorkOrderLogDto;
import com.quectel.core.module.workorder.service.WorkOrderService;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import com.quectel.util.kit.OrderUtils;
import com.quectel.util.kit.StorageKit;
import com.quectel.util.security.UUIDUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * @author caolu
 * @email louis.cao@quectel.com
 * @date 2020-07-07 15:47:11
 */
@RestController
@RequestMapping("videoPatrolEventReport")
@Tag(name = "VideoPatrolEventReportController", description = "视频巡更事件上报相关api")
public class VideoPatrolEventReportController extends BaseController {

    @DubboReference
    private VideoPatrolEventReportService videoPatrolEventReportService;
    @DubboReference
    private WorkOrderService workOrderService;
    @DubboReference
    private VillageService villageService;

    /**
     * 视频巡更事件上报
     */
    @PostMapping("report")
    @RequirePermissions(values = "videoPatrolTask:exec")//可以执行任务就可以上报
    @Operation(summary = "视频巡更事件上报")
    public Response<Object> report(@RequestBody VideoPatrolEventReportDto videoPatrolEventReportDto) throws IOException {

        Date now = new Date();

        //填充基础数据
        fillSaveCommonData(videoPatrolEventReportDto);


        String base64Img = videoPatrolEventReportDto.getSnapshotImg();
        videoPatrolEventReportDto.setSnapshotImg(null);
        if (base64Img != null && base64Img.contains(",")) {
            base64Img = base64Img.substring(base64Img.indexOf(",") + 1);
        }
        if (base64Img != null) {
            byte[] decode = Base64.getDecoder().decode(base64Img);
            File tempFile = new File(FileUtils.getTempDirectory(), UUIDUtils.gen32UUID() + ".jpeg");
            try (ByteArrayInputStream bais = new ByteArrayInputStream(decode);
                 FileOutputStream fos = new FileOutputStream(tempFile)
            ) {
                IOUtils.copyLarge(bais, fos);
                videoPatrolEventReportDto.setSnapshotImg(StorageKit.uploadToPublicBucketObtainUrl(tempFile));
            } finally {
                if (tempFile != null && tempFile.exists()) {
                    tempFile.delete();
                }
            }
        }
        if (SystemConstants.NO.equals(videoPatrolEventReportDto.getAssignWorkOrder())) {
            videoPatrolEventReportDto.setAssignUserId(null);
            videoPatrolEventReportDto.setAssignUsername(null);
        } else {
            //生成工单
            WorkOrderDto workOrderDto = new WorkOrderDto();
            workOrderDto.setOrderSource(WorkOrderConstants.ORDER_SOURCE_ADMIN);
            workOrderDto.setOrderCode(OrderUtils.getOrderNo(OrderCodePrefixConstants.WORK_ORDER_PREFIX));
            workOrderDto.setHandlerId(videoPatrolEventReportDto.getAssignUserId());
            workOrderDto.setVillageId(videoPatrolEventReportDto.getVillageId());
            workOrderDto.setCategory(WorkOrderConstants.CategoryAndType.VIDEO_PATROL.getCategory());
            workOrderDto.setType(WorkOrderConstants.CategoryAndType.VIDEO_PATROL.getType());
            workOrderDto.setStatus(WorkOrderConstants.ORDER_STATUS_HANDLING);
            workOrderDto.setCreateTime(now);
            workOrderDto.setPictures(JacksonUtils.toJsonString(Arrays.asList(videoPatrolEventReportDto.getSnapshotImg())));
            workOrderDto.setDetail("巡更上报备注:" + videoPatrolEventReportDto.getDetail());
            fillSaveCommonData(workOrderDto);

            List<WorkOrderLogDto> logs = new ArrayList<>();
            WorkOrderLogDto initLog = new WorkOrderLogDto();
            initLog.setHandlerId(SessionHolder.getSysUserId());
            initLog.setOrderStatus(WorkOrderConstants.ORDER_STATUS_INIT);
            initLog.setOrderDes("由管理员:" + SessionHolder.getSysUser().getUsername() + " 创建巡更工单");
            initLog.setCreateTime(workOrderDto.getCreateTime());
            logs.add(initLog);
            WorkOrderLogDto forwordLog = new WorkOrderLogDto();
            forwordLog.setHandlerId(workOrderDto.getHandlerId());
            forwordLog.setOrderStatus(WorkOrderConstants.ORDER_STATUS_HANDLING);
            forwordLog.setOrderDes("由管理员:" + SessionHolder.getSysUser().getUsername() + " 指派巡更工单");
            forwordLog.setCreateTime(workOrderDto.getCreateTime());
            logs.add(forwordLog);

            workOrderDto.setWorkOrderLogDtoList(logs);

            Long workOrderId = workOrderService.saveOrUpdateWorkOrderAndLog(workOrderDto);


            videoPatrolEventReportDto.setWorkOrderId(workOrderId);
            videoPatrolEventReportDto.setWorkOrderNo(workOrderDto.getOrderCode());
        }
        Long id = videoPatrolEventReportService.save(videoPatrolEventReportDto);

        return Response.ok();
    }

    /**
     * 根据条件查询所有视频巡更事件
     */
    @GetMapping("queryAllBy")
    @Operation(summary = "根据条件查询所有视频巡更事件")
    public Response<List<VideoPatrolEventReportDto>> queryAllBy(@RequestParam Map<String, Object> params) {
        //查询列表数据
        Request request = Request.configParams(params);
        super.fillAuthorityData(params);

        List<VideoPatrolEventReportDto> list = videoPatrolEventReportService.queryList(params);
        for (VideoPatrolEventReportDto videoPatrolEventReportDto : list) {
            VillageDto villageDto = villageService.selectById(videoPatrolEventReportDto.getVillageId());
            videoPatrolEventReportDto.setVillageDto(villageDto);
            if (SystemConstants.YES.equals(videoPatrolEventReportDto.getAssignWorkOrder())) {
                WorkOrderDto workOrderDto = workOrderService.selectById(videoPatrolEventReportDto.getWorkOrderId());
                videoPatrolEventReportDto.setWorkOrderStatus(workOrderDto == null ? null : workOrderDto.getStatus());
            }
        }
        return Response.<List<VideoPatrolEventReportDto>>ok().wrap(list);
    }

    /**
     * 根据条件查询视频巡更事件分页查询列表
     */
    @GetMapping("list")
    @RequirePermissions(values = "videoPatrolEventReport:list")
    @Operation(summary = "根据条件查询视频巡更事件分页查询列表")
    public Response<Page<VideoPatrolEventReportDto>> list(@RequestParam Map<String, Object> params) {
        //查询列表数据
        Request request = Request.configParams(params);
        super.fillAuthorityData(params);
        int total = videoPatrolEventReportService.queryTotal(params);

        List<VideoPatrolEventReportDto> list = null;
        if (total > 0) {
            list = videoPatrolEventReportService.queryList(params);
            for (VideoPatrolEventReportDto videoPatrolEventReportDto : list) {
                VillageDto villageDto = villageService.selectById(videoPatrolEventReportDto.getVillageId());
                videoPatrolEventReportDto.setVillageDto(villageDto);
                if (Byte.valueOf("1").equals(videoPatrolEventReportDto.getAssignWorkOrder())) {
                    WorkOrderDto workOrderDto = workOrderService.selectById(videoPatrolEventReportDto.getWorkOrderId());
                    videoPatrolEventReportDto.setWorkOrderStatus(workOrderDto == null ? null : workOrderDto.getStatus());
                }
            }
        } else {
            list = new ArrayList<>();
        }

        Page<VideoPatrolEventReportDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<VideoPatrolEventReportDto>>ok().wrap(page);
    }


    /**
     * 信息
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "videoPatrolEventReport:info")
    @Operation(summary = "根据id查询视频巡更事件记录")
    public Response<VideoPatrolEventReportDto> info(@PathVariable("id") Long id) {

        VideoPatrolEventReportDto videoPatrolEventReportDto = videoPatrolEventReportService.selectById(id);

        return Response.<VideoPatrolEventReportDto>ok().wrap(videoPatrolEventReportDto);
    }

    /**
     * 保存
     */
    @PostMapping("save")
    @RequirePermissions(values = "videoPatrolEventReport:edit")
    @Operation(summary = "保存视频巡更事件记录")
    public Response<Object> save(@RequestBody @Validated VideoPatrolEventReportDto videoPatrolEventReportDto) {

        //填充基础数据
        fillSaveCommonData(videoPatrolEventReportDto);

        videoPatrolEventReportService.save(videoPatrolEventReportDto);

        return Response.ok();
    }

    /**
     * 修改
     */
    @PostMapping("update")
    @RequirePermissions(values = "videoPatrolEventReport:edit")
    @Operation(summary = "更新视频巡更事件记录")
    public Response<Object> update(@RequestBody @Validated VideoPatrolEventReportDto videoPatrolEventReportDto) {

        //填充基础数据
        fillEditCommonData(videoPatrolEventReportDto);

        videoPatrolEventReportService.updateById(videoPatrolEventReportDto);

        return Response.ok();
    }

    /**
     * 删除
     */
    @PostMapping("delete")
    @RequirePermissions(values = "videoPatrolEventReport:delete")
    @Operation(summary = "批量删除视频巡更事件记录")
    public Response<Object> delete(@RequestBody Long[] ids) {

        videoPatrolEventReportService.deleteBatch(ids);

        return Response.ok();
    }
}
